package com.hmdp.config;

import org.fisco.bcos.sdk.BcosSDK;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.transaction.manager.AssembleTransactionProcessor;
import org.fisco.bcos.sdk.transaction.manager.TransactionProcessorFactory;
import org.fisco.bcos.sdk.transaction.model.dto.TransactionResponse;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;


@Component
public class DataChainTest {

    //获取配置文件路径
    public final String configFile = "src/main/resources/config-example.toml";

    public BcosSDK bcosSDK ;
    public Client client ;
    public CryptoKeyPair cryptoKeyPair ;
    public KeyPair rsaKeyPair;
    public Base64.Encoder encoder;


//    // 加载智能合约
//    private AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, cryptoKeyPair, "src/main/resources/abi/","");

    //初始化设置
    public DataChainTest() throws Exception {
       //  初始化FISCO BCOS SDK
        bcosSDK = BcosSDK.build(configFile);
        client = bcosSDK.getClient(1);
        cryptoKeyPair = client.getCryptoSuite().createKeyPair();
        client.getCryptoSuite().setCryptoKeyPair(cryptoKeyPair);
        // 生成RSA密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        rsaKeyPair = keyPairGenerator.generateKeyPair();  //生成一对密钥对，保存在rsaKeyPair里面
        encoder = Base64.getEncoder();
    }


//    //获得公钥
//    public String getpublickey(KeyPair keyPair){
//        PublicKey publicKey = keyPair.getPublic();
//        String pubkey = Base64.getEncoder().encodeToString(publicKey.getEncoded());
//        return pubkey;
//    }
//
//    //获得私钥
//    public String getprivatekey(KeyPair keyPair){
//        PrivateKey privateKey = keyPair.getPrivate();
//        String prikey = Base64.getEncoder().encodeToString(privateKey.getEncoded());
//        return prikey;
//    }

    //将数据进行上链
    public void addOrder(String id, String userId, String voucherId, String payType, String status) throws Exception {

        // 加载智能合约
        AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, cryptoKeyPair, "src/main/resources/abi/","");
        // 使用RSA公钥加密数据
//        String encryptedId = rsaEncrypt(id);
//        System.out.println("加密后的id    "+encryptedId);
        String encryptedUserId = rsaEncrypt(userId);
        System.out.println("加密后的用户id"+encryptedUserId);
        String encryptedVoucherId = rsaEncrypt(voucherId);
        String encryptedPayType = rsaEncrypt(payType);
        String encryptedStatus = rsaEncrypt(status);

        // 创建调用交易函数的参数，此处为传入一个参数
        List<Object> params = new ArrayList<>();
         //params.add(encryptedId);
        params.add(id);
        params.add(encryptedUserId);
        params.add(encryptedVoucherId);
        params.add(encryptedPayType);
        params.add(encryptedStatus);


        // 调用智能合约的addOrder方法
        TransactionResponse transactionResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("PatientInsertContract", "0xb0c03b99621ccb5c565ee6d2c705eec6685df9c2", "addPatient", params);
       // System.out.println("区块链返回的状态值是："+transactionResponse.getTransactionReceipt().getStatus());
        if(transactionResponse!=null){
            String flag =transactionResponse.getTransactionReceipt().getStatus();
            if("0x0".equals(flag)){
                // 获取交易哈希
                String transactionHash = transactionResponse.getTransactionReceipt().getTransactionHash();
                System.out.println("订单上链成功,交易哈希: "+transactionHash);
            }else {
                System.out.println("交易上链失败");
                // 获取错误信息
                String errorMessage = transactionResponse.getTransactionReceipt().getMessage();
                System.out.println("错误信息: " + errorMessage);
            }
        }else{
            System.out.println("交易发送失败");
        }

    }


    //从区块链上获取数据
    public void getOrder(String id) throws Exception {

        //将获得的id先进行加密处理
        //String encryptedId = rsaEncrypt(id);
       // System.out.println(encryptedId);
        List<Object> params = new ArrayList<>();
        params.add(id);
        // 加载智能合约
         AssembleTransactionProcessor transactionProcessor = TransactionProcessorFactory.createAssembleTransactionProcessor(client, cryptoKeyPair, "src/main/resources/abi/","");
        // 调用智能合约的getOrder方法
        //Tuple6<String, String, String, String, String, String> result = orderContract.getOrder(rsaEncrypt(id));
        TransactionResponse callResponse = transactionProcessor.sendTransactionAndGetResponseByContractLoader("PatientInsertContract", "0xb0c03b99621ccb5c565ee6d2c705eec6685df9c2", "getPatient",params);

        System.out.println(callResponse);
        System.out.println(callResponse.getReturnObject());
        //打印返回值
        List<Object>getNames = callResponse.getReturnObject();


        System.out.println("链上传回的加密id "+(String)getNames.get(0));
        System.out.println("链上传回的加密userid "+(String)getNames.get(1));
        // 使用RSA私钥解密数据
        //String decryptedId = rsaDecrypt((String)getNames.get(0));
        String decryptedUserId = rsaDecrypt((String)getNames.get(1));
        String decryptedVoucherId = rsaDecrypt((String)getNames.get(2));
        String decryptedPayType = rsaDecrypt((String)getNames.get(3));
        String decryptedStatus = rsaDecrypt((String)getNames.get(4));
     //   String decryptedCreateTime = rsaDecrypt((String)getNames.get(5));

        System.out.println("订单ID: " + (String)getNames.get(0));
        System.out.println("用户ID: " + decryptedUserId);
        System.out.println("优惠券ID: " + decryptedVoucherId);
        System.out.println("支付类型: " + decryptedPayType);
        System.out.println("订单状态: " + decryptedStatus);
       // System.out.println("创建时间: " + decryptedCreateTime);
    }


    //加密算法
    public String rsaEncrypt(String data) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, (RSAPublicKey) rsaKeyPair.getPublic());
        byte[] encryptedBytes = cipher.doFinal(data.getBytes());
        return encoder.encodeToString(encryptedBytes);
    }




    //解密算法
    public String rsaDecrypt(String encryptedData) throws Exception {
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, (RSAPrivateKey) rsaKeyPair.getPrivate());
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes);
    }


    //主方法
    public static void main(String[] args) throws Exception {
        DataChainTest dataChainTest = new DataChainTest();
        // 添加订单数据上链
     //  dataChainTest.addOrder("100", "杨帆", "18025903058", "191224", "1");
        // 查询订单数据
        dataChainTest.getOrder("100");
    }
}
